package org.hawk.gwt.ppc.introspection;

import org.hawk.gwt.ppc.parser.CompilationUnitDescriptor;
import org.hawk.gwt.ppc.parser.ExpressionDescriptor;
import org.hawk.gwt.ppc.scanner.SourcesLoader;
import org.hawk.gwt.ppc.utils.PreprocessorException;

/**
 * Introspection utilities. Provides access point to introspection functionality.
 * @author alex.bereznevatiy@gmail.com
 *
 */
public final class IntrospectionUtils {
	private IntrospectionUtils() {}
	
	/**
	 * Prepares package to be parsed.
	 * All visible classes/interfaces/enums/annotations in this package will be cached
	 * in the internal storage. Visible entities are the entities that can be accessed
	 * from outside of compilation unit (i.e. non-private with non-private path). 
	 * @param packageName to resolve
	 * @param sourcesLoader to load classes 
	 */
	public static void preparsePackage(String packageName, SourcesLoader loader) {
		
	}
	
	/**
	 * Loads java type by its name in the context passed.
	 * Returned type instance depends on context and sources root.
	 * Class name can be as fully qualified name, as just simple name
	 * of the class. Also this method accepts links to member classes.
	 * @param className to resolve
	 * @param context
	 * @param loader
	 * @return introspection java type with name specified
	 * @throws NoSuchTypeException in case there is no such a type
	 * @throws PreprocessorException in case of other troubles
	 */
	public static JavaType resolveType(String className, 
			CompilationUnitDescriptor context, SourcesLoader loader)
			throws PreprocessorException {
		return null;
	}
	
	/**
	 * Creates introspection java type for class passed.
	 * This method is used for the classes which source is unavailable
	 * in the classpath (basically this holds only for JRE classes). 
	 * @param cls to introspect
	 * @return introspection java type for class passed.
	 */
	public static JavaType getType(Class<?> cls) {
		return null;
	}
	
	/**
	 * Checks the expression passed for the result type.
	 * This means that whole expression will be evaluated
	 * and corresponding type will be 100% guaranteed.
	 * 
	 * Note that expression should be valid. This means that 
	 * it should begins with valid java identifier and ends with
	 * semicolon or dot. General requirement is - expression 
	 * should be compilable (this all the methods and variables 
	 * should be declared and there are no syntax errors neither
	 * in current class nor in referred ones). 
	 * 
	 * Also note that iterator passed will not be changed and will
	 * point at the same index as before calling this method.
	 * 
	 * @param expression to evaluate
	 * @param context compilation unit name
	 * @param loader to load the context-related types 
	 * @return the return type of this expression. 
	 * If expression doesn't returns any value (return type is void) 
	 * - <code>null</code> will be returned as a result.
	 * If return type contains some type parameters - they also will
	 * be include in introspection type info.
	 * @throws PreprocessorException in case of troubles.
	 */
	public static JavaType evaluateReturnTypeOfExpression(
			ExpressionDescriptor expression, 
			CompilationUnitDescriptor context,
			SourcesLoader loader)
			throws PreprocessorException{
		
		return null;
	}
}
